package com.example.spring.code.a05;

import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.*;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;
import java.util.Set;

/**
 * BeanFactory 后处理器的作用
 */
public class A05 {

    private static final Logger log = LoggerFactory.getLogger(A05.class);

    public static void main(String[] args) throws IOException {
        // ⬇️GenericApplicationContext 是一个【干净】的容器
        GenericApplicationContext context = new GenericApplicationContext();
        context.registerBean("config", Config.class);

//        context.registerBean(ConfigurationClassPostProcessor.class); // @ComponentScan @Bean @Import @ImportResource
//        context.registerBean(MapperScannerConfigurer.class, bd -> {
//            bd.getPropertyValues().add("basePackage", "com.example.spring.code.a05.mapper");
//        }); // @MapperScan
        /*
            模拟实现
         */
//        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
//        if (componentScan != null) {
//            for (String basePackage : componentScan.basePackages()) {
//                log.info("扫描包：{}", basePackage);
//                String path = "classpath*:" + basePackage.replace(".", "/") + "/**/*.class";
//                log.info("扫描路径：{}", path);
//                Resource[] resources = context.getResources(path);
//                CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
//                AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
//                Arrays.stream(resources).forEach(resource -> {
////                    log.info("扫描到资源：{}", resource.getDescription());
//                    try {
//                        MetadataReader reader = factory.getMetadataReader(resource);
//                        AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
////                        System.out.println("类名：" + reader.getClassMetadata().getClassName());
////                        System.out.println("是否加了 @Component：" + reader.getAnnotationMetadata().hasAnnotation(Component.class.getName()));
////                        System.out.println("是否加了 @Component 派生：" + reader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName()));
//
//                        if (annotationMetadata.hasAnnotation(Component.class.getName())
//                                || annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
//                            AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(reader.getClassMetadata().getClassName()).getBeanDefinition();
//                            DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
//                            String name = generator.generateBeanName(beanDefinition, beanFactory);
//                            beanFactory.registerBeanDefinition(name, beanDefinition);
//                        }
//                    } catch (IOException e) {
//                        throw new RuntimeException(e);
//                    }
//                });
//
//
//            }
//        }



//        context.registerBean(ComponentScanPostProcessor.class); // 将自定义的 ComponentScanPostProcessor 注册到容器中，解析 @ComponentScan 注解


//        CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
//        MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/example/spring/code/a05/Config.class"));
//        Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
//        methods.stream().forEach(method -> {
//            System.out.println(method);
//            String initMethod = method.getAllAnnotationAttributes(Bean.class.getName()).get("initMethod").get(0).toString();
//
//
//            BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
//            builder.setFactoryMethodOnBean(method.getMethodName(), "config");
//            builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR); // 对应构造方法的参数、对于工厂方法的参数，自动装配方式选择 AUTOWIRE_CONSTRUCTOR
//            if (initMethod.length() > 0) {
//                builder.setInitMethodName(initMethod);
//            }
//            AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
//            context.getDefaultListableBeanFactory().registerBeanDefinition(method.getMethodName(), beanDefinition);
//        });

        context.registerBean(AtBeanPostProcessor.class); // 添加自定义的 AtBeanPostProcessor，解析 @Bean 注解

        context.registerBean(MapperPostProcessor.class); // 添加自定义的 MapperPostProcessor，解析 @Mapper 注解



        // 初始化容器
        context.refresh();

        for (String beanDefinitionName : context.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }

        context.close();

    }


}
